﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// NotReviewedButNeeded
#pragma once
#include "GcmpDatabase.h"
#include "NdbObjectMemoryModelNode.h"

namespace gcmp
{
    class INdbObjectMemoryModelNodeVisitor;

    //////////////////////////////////////////////////////////////////////////
    class GCMP_DATABASE_EXPORT NdbObjectMemoryModelGroupNode : public NdbObjectMemoryModelNode
    {
        CANNOT_COPY_OR_ASSIGN(NdbObjectMemoryModelGroupNode)
        DEFINE_CAST_DERIVED(gcmp::NdbObjectMemoryModelGroupNode, gcmp::NdbObjectMemoryModelNode)
    public:
        NdbObjectMemoryModelGroupNode(const ClassId & classId, UInt32 version, size_t nPredictedChild) : NdbObjectMemoryModelNode(classId, version)
        {
            m_opSubNodes.reserve(nPredictedChild);
        }

        const std::vector<OwnerPtr<NdbObjectMemoryModelNode>>& GetSubNodes() const { return m_opSubNodes; }
        std::vector<OwnerPtr<NdbObjectMemoryModelNode>>& GetSubNodesFW() { return m_opSubNodes; }

        const NdbObjectMemoryModelNode * GetSubNode(const std::wstring& name) const;
        NdbObjectMemoryModelNode * GetSubNodeFW(const std::wstring& name);

        void AddSubNode(OwnerPtr<NdbObjectMemoryModelNode> opSubNode)
        {
            m_opSubNodes.emplace_back(std::move(opSubNode));
        }
        // 如果找不到对应名字的子节点，则返回nullptr。否则返回被删掉的节点
        OwnerPtr<NdbObjectMemoryModelNode> RemoveSubNode(const std::wstring& name);
        // 如果找不到对应名字的子节点，则返回false
        bool RenameSubNode(const std::wstring& oldName, const std::wstring& newName);
        // 如果找不到对应名字的子节点，则返回false
        bool ReplaceSubNode(const std::wstring& name, OwnerPtr<NdbObjectMemoryModelNode> opNode);

        void SetParentNode(OwnerPtr<NdbObjectMemoryModelNode> opParentNode)
        {
            m_opParentNode = TransferOwnership(opParentNode);
        }

        const OwnerPtr<NdbObjectMemoryModelNode>& GetParentNode() const { return m_opParentNode; }
        OwnerPtr<NdbObjectMemoryModelNode>& GetParentNodeFW() { return m_opParentNode; }

        virtual NdbObjectMemoryModelNodeType GetType() const override { return NdbObjectMemoryModelNodeType::Group; }

        virtual bool IsLeaf() const override { return false; }

        virtual UInt64 GetDataSize() const override;

        virtual const void * GetData() const override;

        virtual void * GetDataForWrite() override;

        // 对比两个节点是否相同，返回值表示是否继续比较，对组节点来说，发现结构不同返回false。
        virtual bool Compare(
            const NdbObjectMemoryModelNode& another,
            const std::vector<std::pair<std::wstring, std::wstring>>& attributes,
            const NdbElementExportOrCompareOptions& options,
            int level,
            bool & areEqual,
            bool reportNotEqual,
            std::wostringstream& woss
        ) const override;

        virtual void Accept(INdbObjectMemoryModelNodeVisitor * visitor) override;

    public:
        void* operator new(std::size_t count);
        void operator delete(void* ptr);

    private:
        OwnerPtr<NdbObjectMemoryModelNode>              m_opParentNode; // 该节点的属于父类的属性挂在 m_pParentNode下，可为空
        std::vector<OwnerPtr<NdbObjectMemoryModelNode>> m_opSubNodes;   // 该节点的属性
    };
}

